package com.cloudspace.jindun.activity.dianhua;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.TextView;

import com.cloudspace.jindun.JindunApp;
import com.cloudspace.jindun.R;
import com.cloudspace.jindun.activity.CustomTitleBaseActivity;
import com.cloudspace.jindun.config.Configs;
import com.cloudspace.jindun.dao.PhoneRecord;
import com.cloudspace.jindun.ext.aq.AQUtility;
import com.cloudspace.jindun.log.APPLog;
import com.cloudspace.jindun.manager.PhoneRecordManager;
import com.cloudspace.jindun.model.Person;
import com.cloudspace.jindun.net.manager.ImageManager;
import com.cloudspace.jindun.utils.MMAlert;
import com.cloudspace.jindun.utils.ObjUtil;
import com.cloudspace.jindun.utils.TimeUtils;
import com.linphone.LinphoneManager;
import com.linphone.LinphoneUtils;

import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCoreListenerBase;
import org.linphone.mediastream.Log;

import java.util.List;

import static com.cloudspace.jindun.R.id.incoming_answer;
import static com.cloudspace.jindun.R.id.incoming_refuse;
import static com.cloudspace.jindun.R.id.phone_ll_callSpeaker;
import static com.cloudspace.jindun.R.id.phone_ll_hangup;
import static com.cloudspace.jindun.R.id.phone_ll_stopCall;
import static com.cloudspace.jindun.R.string.call;

/**
 * Created by zengxianhua on 16/12/24.
 */

public class CallActivity extends CustomTitleBaseActivity implements View.OnClickListener, ActivityCompat.OnRequestPermissionsResultCallback {
    public String sipAddress = null;

    private ImageView head;
    private TextView name;
    private TextView phoneNumber;
    private TextView companyName;

    private TextView state;
    private Chronometer timer;

    private View callingView;
    private Button hangupBtn;

    private ImageView loudSpeakerView;

    private boolean callSuccess = false;
    private boolean isMicMuted;
    private boolean isSpeakerEnabled;
    private LinphoneCall mCall;

    private LinphoneCoreListenerBase mListener = new LinphoneCoreListenerBase(){
        @Override
        public void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State state, String message) {
            if (call != mCall){
                return;
            }

            if (LinphoneCall.State.Connected == state) {
                //接通
                calling();
            }else if (LinphoneCall.State.CallEnd == state
                    || LinphoneCall.State.CallReleased == state){
                hangout(false);
            }else if (state == LinphoneCall.State.Error){
                 //异常情况
                 notSuccess(call.getErrorInfo().getReason().toString());
            }
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call);
        getTitleBar().setSimpleMode(getString(call));
        getTitleBar().setTitleBarBackground(R.color.light_black);

        initView();

        if (JindunApp.getInstance().registerSipSuccess()){
            makeCall();
        }else{
            MMAlert.showAlert(this, getResources().getString(R.string.sip_register_fail), getResources().getString(R.string.dialog_default_title), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    finish();
                }
            });
            return;
        }

        LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
        if (lc != null) {
            lc.addListener(mListener);
        }

        // Only one call ringing at a time is allowed
        if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
            List<LinphoneCall> calls = LinphoneUtils.getLinphoneCalls(LinphoneManager.getLc());
            for (LinphoneCall call : calls) {
                LinphoneCall.State cstate = call.getState();
                if (LinphoneCall.State.OutgoingInit == cstate || LinphoneCall.State.OutgoingProgress == cstate
                        || LinphoneCall.State.OutgoingRinging == cstate || LinphoneCall.State.OutgoingEarlyMedia == cstate) {
                    mCall = call;
                    break;
                }
                if (LinphoneCall.State.StreamsRunning == cstate) {
                    calling();
                }
            }
        }
        if (mCall == null) {
            Log.e("Couldn't find outgoing call");
            finish();
            return;
        }
    }

    Person callingPerson;

    private View stopCallBtn;
    private void initView() {
        head = (ImageView) findViewById(R.id.phone_iv_head);
        name  = (TextView) findViewById(R.id.phone_tv_name);
        phoneNumber = (TextView) findViewById(R.id.phone_tv_tele);
        companyName = (TextView) findViewById(R.id.phone_tv_remarkName);
        state = (TextView) findViewById(R.id.phone_tv_callState);
        state.setText(getString(R.string.call_wait));
        timer = (Chronometer) findViewById(R.id.chronometer);
        timer.setVisibility(View.GONE);
        callingView = findViewById(R.id.calling);
        callingView.setVisibility(View.GONE);
        hangupBtn = (Button) findViewById(phone_ll_hangup);
        hangupBtn.setOnClickListener(this);

        loudSpeakerView = (ImageView) findViewById(R.id.phone_ll_callSpeaker);
        loudSpeakerView.setOnClickListener(this);

        stopCallBtn = findViewById(phone_ll_stopCall);
        stopCallBtn.setVisibility(View.VISIBLE);
        stopCallBtn.setOnClickListener(this);

        Intent intent = getIntent();
        callingPerson = (Person) intent.getSerializableExtra("person");
        if (callingPerson != null) {
            ImageManager.loadCircleImage(this, head, callingPerson.getImageUrl(), Configs.IMAGE_CORNER_RADIUS);
            name.setText(callingPerson.getName());
            phoneNumber.setText(callingPerson.getPhoneNumber());
            companyName.setText(callingPerson.getCompany());
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        addARecord();

        LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
        if (lc != null) {
            lc.removeListener(mListener);
        }
    }

    /**
     * Make an outgoing call.
     */
    public void makeCall() {
        if (ObjUtil.isEmpty(callingPerson)){
            APPLog.zxhLog("callingPerson null");
            return;
        }

        sipAddress  = callingPerson.getSipAccount();

        if (TextUtils.isEmpty(sipAddress)){
            APPLog.zxhLog("sipAddress null return...");
            return;
        }

        if (!sipAddress.startsWith("sip:")){
            sipAddress = "sip:" + sipAddress;
        }
        APPLog.zxhLog("call to sip:" + sipAddress);
        LinphoneManager.getInstance().newOutgoingCall(sipAddress, callingPerson.getName());
    }

    private void addARecord() {
        if (callingPerson == null){
            APPLog.d("zxh", "callingPerson == null");
            return;
        }

        PhoneRecord record = new PhoneRecord();
        record.setUserid(String.valueOf(callingPerson.getUserId()));
        record.setImage(callingPerson.getImageUrl());

        if (callSuccess){
            record.setCallfrom(CallInOrOut.OUTCALL);
        }else{
            record.setCallfrom(CallInOrOut.CALLFAIL);
        }


        String timeStr = TimeUtils.getNowTimeString();
        record.setDaystr(timeStr.split(" ")[0]);

        String hmStr = timeStr.split(" ")[1];
        record.setTime(timeStr);

        record.setTimestamp(System.currentTimeMillis());

        record.setHm(hmStr.substring(0, hmStr.lastIndexOf(":")));
        record.setName(callingPerson.getName());

        PhoneRecordManager.getInstance().addPhoneRecord(record);
    }

    private void notSuccess(final String text) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                state.setText(text);
                stopCallBtn.setVisibility(View.GONE);

            }
        });

        AQUtility.post(new Runnable() {
            @Override
            public void run() {
                decline();
                finish();
            }
        });
    }

    public void calling() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                timer.setVisibility(View.VISIBLE);
                timer.start();
                callSuccess = true;
                state.setText(getResources().getString(R.string.call_online));
                showCallingView();
            }
        });

    }

    private void noAnswer(){
        hangout(true);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case phone_ll_hangup:
                hangout(true);
                break;

            case incoming_answer:
                calling();
                break;

            case incoming_refuse:
                refuse();
                break;

            case phone_ll_callSpeaker:
                switchSpeakerMode();
                break;

            case phone_ll_stopCall:
                stopCall();
                break;
            
            default:
                break;
        }
    }

    private void stopCall() {
        hangout(true);
    }

    private void switchSpeakerMode() {
        toggleSpeaker();
    }

    private void decline() {
        LinphoneManager.getLc().terminateCall(mCall);
    }

    private void refuse() {
        hangout(false);
    }

    public void hangout(boolean isMe) {
        if (timer != null){
            timer.stop();
        }

        showCompleteView(isMe);
        decline();
    }

    //通话结束界面
    //自己挂断，isMe为true
    private void showCompleteView(final boolean isMe) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (timer != null){
                    timer.setVisibility(View.GONE);
                }

                callingView.setVisibility(View.GONE);
                stopCallBtn.setVisibility(View.GONE);

                if (isMe){
                    if (state != null){
                        state.setText(getString(R.string.hang_out));
                        state.setTextColor(getResources().getColor(R.color.red_1));
                    }
                }else{
                    if (state != null){
                        state.setText(getString(R.string.other_hang_out));
                        state.setTextColor(getResources().getColor(R.color.red_1));
                    }
                }
            }
        });

        AQUtility.postDelayed(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        }, 500);
    }

    private void showCallingView(){
        callingView.setVisibility(View.VISIBLE);
        stopCallBtn.setVisibility(View.GONE);
    }

    private void toggleSpeaker() {
        isSpeakerEnabled = !isSpeakerEnabled;
        if (isSpeakerEnabled) {
            LinphoneManager.getInstance().routeAudioToSpeaker();
            loudSpeakerView.setImageResource(R.drawable.speaker_selected);
            LinphoneManager.getLc().enableSpeaker(isSpeakerEnabled);
        } else {
            APPLog.d("Toggle speaker off, routing back to earpiece");
            LinphoneManager.getInstance().routeAudioToReceiver();
            loudSpeakerView.setImageResource(R.drawable.speaker);
        }
    }

}
